package com.simen.hellobytes.io;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;

public class LineInputStream {

    private static final int BUFSIZE = 2048;
    private InputStream inputStream;
    private int boundaryLength;
    private byte[] boundary;
    private ByteBuffer byteBuffer, cacheByteBuffer;
    private byte[] cacheByte;
    private boolean lastByteIsCR = false;
    private boolean readContent = false;
    private int lastNewLineIndex = -1;
    private boolean readEOF = false;

    public LineInputStream(InputStream inputStream, byte[] boundary, int boundaryLength) {
        this.inputStream = inputStream;
        this.boundary = boundary;
        this.boundaryLength = boundaryLength;
        this.byteBuffer = ByteBuffer.allocateDirect(BUFSIZE);
        this.cacheByteBuffer = ByteBuffer.allocateDirect(BUFSIZE);
        this.cacheByte = new byte[BUFSIZE];
    }

    //注意：boundary相关信息行长度不会超过byteBuffer容量
    //读取boundary信息
    public byte[] readBoundaryLine() throws IOException {
        if (!readEOF) {
            byteBuffer.limit(byteBuffer.capacity());
            readStream();
        }

        byteBuffer.flip();
        for (; byteBuffer.hasRemaining(); ) {
            byte b = byteBuffer.get();

            if (b == '\r') {
                lastByteIsCR = true;
            } else if (b == '\n') {
                if (lastByteIsCR) {
                    lastByteIsCR = false;
                }
                return getLineBytes(true);
            } else {
                if (lastByteIsCR) {
                    lastByteIsCR = false;
                    return getLineBytes(false);
                }
            }
        }

        return readBoundaryLine();
    }

    //读取文件内容
    public int readFile(byte[] buf, int offset, int length) throws IOException {
        return 0;
    }

    private void readStream() throws IOException {
        while (byteBuffer.hasRemaining()) {
            byte[] buf = new byte[byteBuffer.remaining()];
            int read = inputStream.read(buf, 0, buf.length);
            if (read == -1) {
                readEOF = true;
                break;
            }

            byteBuffer.put(buf, 0, read);
        }
    }

    private byte[] getLineBytes(boolean isLF) {
        int position = isLF ? byteBuffer.position() : byteBuffer.position() - 1;
        byte[] line = new byte[position];

        byteBuffer.rewind();
        byteBuffer.get(line, 0, line.length);

        int remaining = byteBuffer.remaining();
        if (remaining > 0) {
            byteBuffer.get(cacheByte, 0, remaining);
            byteBuffer.clear();
            byteBuffer.put(cacheByte, 0, remaining);
        }

        return line;
    }

}
